package com.zilu.digitaltwin.common.exception;

import com.zilu.digitaltwin.common.response.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author heguangyao
 * @Date 2023/1/3 11:13
 */
@RestControllerAdvice
@Slf4j
public class ControllerExceptionHandler {


    @ExceptionHandler(value = CommonException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public Response CommonExceptionHandler(Throwable e, HttpServletRequest request) {
        String message = e.getMessage();
        CommonException commonException = (CommonException) e;
        log.error("request url ：{}, common exception ", request.getRequestURL(), e);
        return Response.custom(commonException.getErrorCode().getStatusCode(), message);
    }

    /**
     * 未知异常 统一处理
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Response exceptionHandler(Exception e, HttpServletRequest request) {
        String message = e.getMessage();
        if (e instanceof UndeclaredThrowableException) {
            Throwable undeclaredThrowable = ((UndeclaredThrowableException) e).getUndeclaredThrowable();
            message = undeclaredThrowable.getMessage();
        }
        log.error("request url ：{}", request.getRequestURL(), e);
        return Response.failed(message);
    }

    /**
     * Valid注解 校验异常处理
     *
     * @param e       BindException 异常
     * @param request 请求信息
     * @return
     */
    @ExceptionHandler(value = BindException.class)
    @ResponseBody
    public Response exceptionHandler(BindException e, HttpServletRequest request) {
        List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
        String message = allErrors.stream().map(errMsg -> errMsg.getDefaultMessage()).collect(Collectors.joining(","));
        log.error("request url ：{}", request.getRequestURL(), e);
        return Response.failed(message);
    }
}
